package com.douqu.game.merge;

import com.douqu.game.core.database.model.PlayerModel;
import com.douqu.game.core.database.model.UserModel;
import com.douqu.game.core.entity.Player;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2018-03-24 15:33
 */
public class DatabaseFactory {

    private String url;

    private String user;

    private String password;

    public DatabaseFactory(String url, String user, String password)
    {
        this.url = url;
        this.user = user;
        this.password = password;
    }

    private Connection getConnection()
    {
        try {
            // 加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            return DriverManager.getConnection(url, user, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Player loadPlayer(String account)
    {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            connection = getConnection();
            ps = connection.prepareStatement("select * from player where uid = (select id from user where account=? or deviceId=?)");
            ps.setString(1, account);
            ps.setString(2, account);
            rs = ps.executeQuery();
            if(rs.next())
            {
                PlayerModel playerModel = new PlayerModel();
                playerModel.setId(rs.getInt("id"));
                playerModel.setObjectIndex(rs.getString("objectIndex"));
                playerModel.setUid(rs.getInt("uid"));
                playerModel.setName(rs.getString("name"));
                playerModel.setAvatar(rs.getString("avatar"));
                playerModel.setCamp(rs.getInt("camp"));
                playerModel.setLevel(rs.getInt("level"));
                playerModel.setExp(rs.getInt("exp"));
                playerModel.setVipLevel(rs.getInt("vipLevel"));
                playerModel.setVipExp(rs.getInt("vipExp"));
                playerModel.setMaster(rs.getInt("master"));
                playerModel.setFc(rs.getInt("fc"));
                playerModel.setMoney(rs.getInt("money"));
                playerModel.setBagInfo(rs.getBytes("bagInfo"));
                playerModel.setSettingInfo(rs.getBytes("settingInfo"));
                playerModel.setChallengeInfo(rs.getBytes("challengeInfo"));
                playerModel.setTaskInfo(rs.getBytes("taskInfo"));
                playerModel.setBoonInfo(rs.getBytes("boonInfo"));
                playerModel.setMailInfo(rs.getBytes("mailInfo"));
                playerModel.setMajorInfo(rs.getBytes("majorInfo"));
                playerModel.setIsDel(rs.getBoolean("isDel"));
                playerModel.setCreateTime(rs.getTime("createTime"));
                playerModel.setLastLoginTime(rs.getTime("lastLoginTime"));
                playerModel.setLastLogoutTime(rs.getTime("lastLogoutTime"));

                return new Player(playerModel);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if(rs != null)
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            if(ps != null)
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            if(connection != null)
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
        }
        return null;
    }


    public List<MergePlayer> getPlayerList()
    {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<MergePlayer> mergePlayerList = new ArrayList<>();
        try {
            connection = getConnection();
            ps = connection.prepareStatement("select * from user limit 10");
            rs = ps.executeQuery();
            Map<Integer, UserModel> userModelMap = new HashMap<>();
            UserModel userModel = null;
            while(rs.next())
            {
                userModel = new UserModel();
                userModel.setId(rs.getInt("id"));
                userModel.setAccount(rs.getString("account"));
                userModel.setDeviceId(rs.getString("deviceId"));
                userModel.setMobile(rs.getString("mobile"));
                userModel.setPassword(rs.getString("password"));
                userModel.setIp(rs.getString("ip"));
                userModel.setChannel(rs.getInt("channel"));
                userModel.setCreateTime(rs.getTime("createTime"));
                userModel.setIsDel(rs.getBoolean("isDel"));

                userModelMap.put(userModel.getId(), userModel);
            }

            ps = connection.prepareStatement("select * from player where uid != 0 limit 10");
            rs = ps.executeQuery();
            PlayerModel playerModel = null;
            while(rs.next())
            {
                playerModel = new PlayerModel();
                playerModel.setId(rs.getInt("id"));
                playerModel.setObjectIndex(rs.getString("objectIndex"));
                playerModel.setUid(rs.getInt("uid"));
                playerModel.setName(rs.getString("name"));
                playerModel.setAvatar(rs.getString("avatar"));
                playerModel.setCamp(rs.getInt("camp"));
                playerModel.setLevel(rs.getInt("level"));
                playerModel.setExp(rs.getInt("exp"));
                playerModel.setVipLevel(rs.getInt("vipLevel"));
                playerModel.setVipExp(rs.getInt("vipExp"));
                playerModel.setMaster(rs.getInt("master"));
                playerModel.setFc(rs.getInt("fc"));
                playerModel.setMoney(rs.getInt("money"));
                playerModel.setBagInfo(rs.getBytes("bagInfo"));
                playerModel.setSettingInfo(rs.getBytes("settingInfo"));
                playerModel.setChallengeInfo(rs.getBytes("challengeInfo"));
                playerModel.setTaskInfo(rs.getBytes("taskInfo"));
                playerModel.setBoonInfo(rs.getBytes("boonInfo"));
                playerModel.setMailInfo(rs.getBytes("mailInfo"));
                playerModel.setMajorInfo(rs.getBytes("majorInfo"));
                playerModel.setIsDel(rs.getBoolean("isDel"));
                playerModel.setCreateTime(rs.getTime("createTime"));
                playerModel.setLastLoginTime(rs.getTime("lastLoginTime"));
                playerModel.setLastLogoutTime(rs.getTime("lastLogoutTime"));

                mergePlayerList.add(new MergePlayer(userModelMap.get(playerModel.getUid()), playerModel));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if(rs != null)
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            if(ps != null)
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            if(connection != null)
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
        }
        return mergePlayerList;
    }



    public void savePlayerList(List<MergePlayer> playerList)
    {
        Connection connection = null;
        PreparedStatement ps1 = null;
        PreparedStatement ps2 = null;
        try{
            connection = getConnection();
            connection.setAutoCommit(false);

            String sql1 = "insert into user (id,account,deviceId,mobile,password,ip,channel,createTime,isDel) values (?,?,?,?,?,?,?,?,?)";
            String sql2 = "insert into player (id,objectIndex,uid,name,avatar,camp,level,exp,vipLevel,vipExp,master,fc,money," +
                    "bagInfo,settingInfo,challengeInfo,taskInfo,boonInfo,mailInfo,majorInfo," +
                    "isDel,createTime,lastLoginTime,lastLogoutTime) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
            ps1 = connection.prepareStatement(sql1);
            ps2 = connection.prepareStatement(sql2);
            UserModel userModel = null;
            PlayerModel playerModel = null;
            for(MergePlayer player : playerList)
            {
                userModel = player.getUserModel();
                ps1.setInt(1, player.getId());
                ps1.setString(2, userModel.getAccount());
                ps1.setString(3, userModel.getDeviceId());
                ps1.setString(4, userModel.getMobile());
                ps1.setString(5, userModel.getPassword());
                ps1.setString(6, userModel.getIp());
                ps1.setInt(7, userModel.getChannel());
                ps1.setTimestamp(8, new Timestamp(userModel.getCreateTime().getTime()));
                ps1.setBoolean(9, userModel.getIsDel());
                ps1.addBatch();

                playerModel = player.getPlayerModel();
                ps2.setInt(1, player.getId());
                ps2.setString(2, playerModel.getObjectIndex());
                ps2.setInt(3, player.getId());
                ps2.setString(4, playerModel.getName());
                ps2.setString(5, playerModel.getAvatar());
                ps2.setInt(6, playerModel.getCamp());
                ps2.setInt(7, playerModel.getLevel());
                ps2.setInt(8, playerModel.getExp());
                ps2.setInt(9, playerModel.getVipLevel());
                ps2.setInt(10, playerModel.getVipExp());
                ps2.setInt(11, playerModel.getMaster());
                ps2.setInt(12, playerModel.getFc());
                ps2.setInt(13, playerModel.getMoney());
                ps2.setBytes(14, playerModel.getBagInfo());
                ps2.setBytes(15, playerModel.getSettingInfo());
                ps2.setBytes(16, playerModel.getChallengeInfo());
                ps2.setBytes(17, playerModel.getTaskInfo());
                ps2.setBytes(18, playerModel.getBoonInfo());
                ps2.setBytes(19, playerModel.getMailInfo());
                ps2.setBytes(20, playerModel.getMajorInfo());
                ps2.setBoolean(21, playerModel.getIsDel());
                ps2.setTimestamp(22, new Timestamp(playerModel.getCreateTime().getTime()));
                ps2.setTimestamp(23, new Timestamp(playerModel.getLastLoginTime().getTime()));
                if(playerModel.getLastLogoutTime() != null)
                    ps2.setTimestamp(24, new Timestamp(playerModel.getLastLogoutTime().getTime()));
                else
                    ps2.setObject(24, null);
                ps2.addBatch();
            }

            ps1.executeBatch();
            ps2.executeBatch();

            connection.commit();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(ps1 != null)
                try {
                    ps1.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            if(ps2 != null)
                try {
                    ps2.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            if(connection != null)
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
        }
    }
}
